using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using RadioTimer.Models;
using RadioTimer.Services;
using System.Windows.Input;

namespace RadioTimer.ViewModels
{
    /// <summary>
    /// 主页面视图模型类
    /// 继承自BaseViewModel，负责主页面的数据绑定和业务逻辑处理
    /// 提供报时服务的控制、统计信息显示和状态管理功能
    /// 符合MVVM架构模式，实现视图与业务逻辑的分离
    /// </summary>
    public partial class MainPageViewModel : BaseViewModel
    {
        #region 私有字段
        
        /// <summary>
        /// 数据存储服务实例，用于持久化设置和统计数据
        /// </summary>
        private readonly IDataStorageService _dataStorage;
        
        /// <summary>
        /// 时间报时服务实例，提供核心的报时功能
        /// </summary>
        private readonly ITimeChimeService _timeChimeService;
        
        /// <summary>
        /// 前台服务实例，确保应用在后台运行不被杀死
        /// </summary>
        private readonly IForegroundService _foregroundService;

        /// <summary>
        /// 报时统计信息的私有字段
        /// </summary>
        [ObservableProperty]
        private ChimeStatistics _statistics = new();
        
        /// <summary>
        /// 下次报时时间的私有字段
        /// </summary>
        [ObservableProperty]
        private string _nextChimeTime = "未设置";
        
        /// <summary>
        /// 服务状态描述的私有字段
        /// </summary>
        [ObservableProperty]
        private string _serviceStatus = "服务未启动";
        
        /// <summary>
        /// 当前时间显示的私有字段
        /// </summary>
        [ObservableProperty]
        private string _currentTimeDisplay = string.Empty;
        
        /// <summary>
        /// 定时器，用于定时更新当前时间显示
        /// </summary>
        private Timer? _clockTimer;
        
        #endregion

        #region 构造函数
        
        /// <summary>
        /// 初始化MainPageViewModel实例
        /// 通过依赖注入获取所需的服务实例，并订阅相关事件
        /// </summary>
        /// <param name="dataStorage">数据存储服务</param>
        /// <param name="timeChimeService">时间报时服务</param>
        /// <param name="foregroundService">前台服务</param>
        public MainPageViewModel(
            IDataStorageService dataStorage,
            ITimeChimeService timeChimeService,
            IForegroundService foregroundService)
        {
            _dataStorage = dataStorage;
            _timeChimeService = timeChimeService;
            _foregroundService = foregroundService;

            // 订阅服务事件以接收状态变更通知
            _timeChimeService.ChimeTriggered += OnChimeTriggered;
            _timeChimeService.ServiceStatusChanged += OnServiceStatusChanged;
            _foregroundService.StatusChanged += OnForegroundServiceStatusChanged;

            // 启动时钟定时器，每秒更新时间显示
            StartClockTimer();

            // 异步初始化数据，避免阻塞UI线程
            _ = Task.Run(InitializeAsync);
            
            // 记录日志
            Log("MainPageViewModel 初始化完成");
        }
        
        #endregion

        #region 公共属性
        
        /// <summary>
        /// 今日播放次数的显示文本
        /// 格式化显示今日的报时次数
        /// </summary>
        public string TodayCountText => $"今日播放: {Statistics.TodayCount} 次";
        
        /// <summary>
        /// 总计播放次数的显示文本
        /// 格式化显示累计的报时次数
        /// </summary>
        public string TotalCountText => $"总计播放: {Statistics.TotalCount} 次";
        
        /// <summary>
        /// 服务控制按钮的显示文本
        /// 根据当前服务状态动态显示"开启报时"或"关闭报时"
        /// </summary>
        public string ServiceButtonText => _foregroundService.IsRunning ? "关闭报时" : "开启报时";
        
        /// <summary>
        /// 服务控制按钮的颜色
        /// 根据当前服务状态显示不同颜色：启用时为红色，禁用时为主色调
        /// </summary>
        public Color ServiceButtonColor => _foregroundService.IsRunning ? Colors.Red : Color.FromHex("#007ACC");
        
        #endregion

        #region RelayCommand 命令
        
        /// <summary>
        /// 切换服务状态的命令
        /// 绑定到主控制按钮，用于开启或关闭报时服务
        /// </summary>
        [RelayCommand]
        private async Task ToggleServiceAsync()
        {
            try
            {
                // 加载当前设置
                var settings = await _dataStorage.LoadAppSettingsAsync();
                
                // 根据前台服务当前状态决定是启动还是停止
                if (_foregroundService.IsRunning)
                {
                    // 停止报时服务和前台服务
                    await _timeChimeService.StopServiceAsync();
                    await _foregroundService.StopAsync();
                    settings.IsChimeServiceEnabled = false;
                }
                else
                {
                    // 启动前台服务和报时服务
                    await _foregroundService.StartAsync();
                    await _timeChimeService.StartServiceAsync();
                    settings.IsChimeServiceEnabled = true;
                }
                
                // 保存设置
                await _dataStorage.SaveAppSettingsAsync(settings);

                // 更新下次报时时间显示
                await UpdateNextChimeTimeAsync();

                // 通知UI更新按钮显示
                OnPropertyChanged(nameof(ServiceButtonText));
                OnPropertyChanged(nameof(ServiceButtonColor));
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error toggling service: {ex.Message}");
                ServiceStatus = $"操作失败: {ex.Message}";
            }
        }
        
        /// <summary>
        /// 刷新数据的命令
        /// 绑定到刷新按钮，用于手动刷新统计数据和状态信息
        /// </summary>
        [RelayCommand]
        private async Task RefreshDataAsync()
        {
            if (IsBusy) return;
            
            try
            {
                IsBusy = true;
                
                // 加载并刷新统计数据
                var stats = await _dataStorage.LoadStatisticsAsync();
                stats.ResetDailyCount(); // 确保日计数的准确性
                Statistics = stats;

                // 加载应用设置
                var settings = await _dataStorage.LoadAppSettingsAsync();

                // 更新下次报时时间显示
                await UpdateNextChimeTimeAsync();

                // 通知UI更新相关的计算属性
                OnPropertyChanged(nameof(TodayCountText));
                OnPropertyChanged(nameof(TotalCountText));
                OnPropertyChanged(nameof(ServiceButtonText));
                OnPropertyChanged(nameof(ServiceButtonColor));
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error refreshing data: {ex.Message}");
            }
            finally
            {
                IsBusy = false;
            }
        }
        
        #endregion

        #region 私有方法
        
        /// <summary>
        /// 异步初始化方法
        /// 在后台线程中加载初始数据，避免阻塞UI
        /// </summary>
        /// <returns>异步任务</returns>
        private async Task InitializeAsync()
        {
            await RefreshDataAsync();
        }

        /// <summary>
        /// 异步更新下次报时时间显示
        /// 根据当前设置计算并显示下一个报时时间点
        /// </summary>
        /// <returns>异步任务</returns>
        private async Task UpdateNextChimeTimeAsync()
        {
            try
            {
                var nextTime = await _timeChimeService.GetNextChimeTimeAsync();
                NextChimeTime = nextTime?.ToString("MM-dd HH:mm") ?? "无下次报时";
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error updating next chime time: {ex.Message}");
                NextChimeTime = "获取失败";
            }
        }
        
        /// <summary>
        /// 启动时钟定时器
        /// 每秒更新一次时间显示
        /// </summary>
        private void StartClockTimer()
        {
            _clockTimer = new Timer(UpdateCurrentTime, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
        }
        
        /// <summary>
        /// 停止时钟定时器
        /// </summary>
        private void StopClockTimer()
        {
            _clockTimer?.Dispose();
            _clockTimer = null;
        }
        
        /// <summary>
        /// 更新当前时间显示
        /// 包含阳历、农历、星期信息
        /// </summary>
        /// <param name="state">定时器状态</param>
        private void UpdateCurrentTime(object? state)
        {
            try
            {
                var now = DateTime.Now;
                // 使用CalendarHelper获取星期和农历日期
                var calendarHelper = new CalendarHelper();
                var dateInfo = calendarHelper.GetDateTidyInfo(now);
                var weekday = dateInfo.DayInWeek; // 提取星期几的数字部分
                var lunarDate = calendarHelper.GetLunarDateString(now);
                
                var timeDisplay = $"{now:yyyy年M月d日} {weekday}";
                if (!string.IsNullOrEmpty(lunarDate))
                {
                    timeDisplay += $" {lunarDate}";
                }
                timeDisplay += $" {now:HH:mm:ss}";

                // 在主线程中更新UI
                MainThread.BeginInvokeOnMainThread(() =>
                {
                    CurrentTimeDisplay = timeDisplay;
                });
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error updating current time: {ex.Message}");
            }
        }

        
        /// <summary>
        /// 中文化服务状态显示
        /// </summary>
        /// <param name="status">英文状态</param>
        /// <returns>中文状态</returns>
        private string LocalizeServiceStatus(string status)
        {
            return status?.ToLower() switch
            {
                "service started" => "服务已启动",
                "service stopped" => "服务已停止",
                "service running" => "服务运行中",
                "service error" => "服务错误",
                "starting" => "正在启动...",
                "stopping" => "正在停止...",
                "ready" => "就绪",
                "idle" => "空闲",
                "active" => "活跃",
                "inactive" => "非活跃",
                _ => status ?? "未知状态"
            };
        }
        
        #endregion

        #region 事件处理方法
        
        /// <summary>
        /// 报时触发事件处理方法
        /// 当成功执行报时时被调用，自动刷新统计数据
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="chimeTime">报时时间</param>
        private async void OnChimeTriggered(object? sender, DateTime chimeTime)
        {
            await RefreshDataAsync();
        }

        /// <summary>
        /// 报时服务状态变更事件处理方法
        /// 更新服务状态显示
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="status">状态描述</param>
        private void OnServiceStatusChanged(object? sender, string status)
        {
            ServiceStatus = LocalizeServiceStatus(status);
        }

        /// <summary>
        /// 前台服务状态变更事件处理方法
        /// 更新前台服务状态显示
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="status">状态描述</param>
        private void OnForegroundServiceStatusChanged(object? sender, string status)
        {
            ServiceStatus = $"{LocalizeServiceStatus(status)}";
        }
        
        #endregion

        #region 资源清理

        /// <summary>
        /// 清理资源和取消事件订阅
        /// </summary>
        public void Dispose()
        {
            try
            {
                // 停止时钟定时器
                StopClockTimer();

                // 取消事件订阅
                _timeChimeService.ChimeTriggered -= OnChimeTriggered;
                _timeChimeService.ServiceStatusChanged -= OnServiceStatusChanged;
                _foregroundService.StatusChanged -= OnForegroundServiceStatusChanged;
            }
            catch (Exception ex)
            {
                Services.DebugLogger.WriteError($"Error disposing MainPageViewModel: {ex.Message}");
            }
        }

        #endregion
    }
}